package network.handlers;

import java.io.IOException;

import state.Globals;
import state.group.GroupDispatcherState;
import state.group.HallCall;
import state.group.events.PersonDispatcherEvent;
import network.ConnectionMode;
import network.managers.ObserverManager;
import network.server.ModeHandlerThread;
import managers.ElevatorManager;
import managers.HallCallManager;
import messages.BaseMessage;
import messages.GeneralAck;
import messages.MessageType;
import messages.persondispatcher.RegisterHallCallMessage;

public class PersonDispatcherModeHandler extends ObserverModeHandler {
    
    public PersonDispatcherModeHandler(ModeHandlerThread parent)
    {
        super(parent);
    }
    
    public boolean enterMode(byte id)
    {
        GroupDispatcherState state = ElevatorManager.getInstance().getDispatcherState();
        
        boolean success = state.personDispatcherAddress == parent.getRemoteSocket().getInetAddress();
        
        GeneralAck ack = new GeneralAck(MessageType.PersonDispatcherRegistrationMessage, success);
        try
        {
            parent.getRemoteSocket().getOutputStream().write(ack.toByteArray());
        }
        catch (IOException e)
        {
            Globals.getLogger().error("Error occurred while sending out the registration ack", e);
            return false;
        }
        
        if (success)
        {
            PersonDispatcherEvent event = new PersonDispatcherEvent(true);
            
            ObserverManager.getInstance().postEvent(event);
            
            success = ObserverManager.getInstance().registerObserver(parent);
            
            if (success)
            {
            	Thread.currentThread().setName("Person Dispatcher Handler " + Thread.currentThread().getId());
            	
            	return true;
            }
            return false;
        }
        else
        {
            return false;
        }
    }
    
    @Override
    public void exitMode()
    {
        super.exitMode();
        
        GroupDispatcherState state = ElevatorManager.getInstance().getDispatcherState();
        
        state.personDispatcherAddress = null;
        state.personDispatcherListeningPort = -1;
        
        PersonDispatcherEvent event = new PersonDispatcherEvent(false);
        
        ObserverManager.getInstance().postEvent(event);
    }

    @Override
    public ConnectionMode handleMessage(BaseMessage message)
    {
        if (message == null)
        {
            ConnectionMode retVal = super.handleMessage(message);
            if (retVal != super.getMode())
            {
                return retVal;
            }
            else
            {
                return getMode();
            }
        }
        
        if (message.getMessageType().equals(MessageType.RegisterHallCallMessage))
        {
            
            RegisterHallCallMessage mess = (RegisterHallCallMessage) message;
            HallCall call = mess.getHallCall();
            
            System.out.println("Received Hall Call for floor: " + call.getFloor() + "; direction: " + call.getDirection());
            
            HallCallManager.getInstance().registerHallCall(call);
            
            return getMode();
        }
        else
        {
            ConnectionMode retVal = super.handleMessage(message);

            if (retVal != super.getMode())
            {
                return retVal;
            }
            else
            {
                return getMode();
            }
        }

    }

    @Override
    public ConnectionMode getMode()
    {
        return ConnectionMode.PersonDispatcher;
    }

}
